package com.ruoyi.module.controller;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.module.domain.DictBook;
import com.ruoyi.module.domain.DictBookUser;
import com.ruoyi.module.domain.DictWord;
import com.ruoyi.module.mapper.DictWordMapper;
import com.ruoyi.module.service.IDictBookService;
import com.ruoyi.module.service.IDictBookUserService;

/**
 * 词典Controller
 * 
 * @author ruoyi
 */
@RestController
@RequestMapping("/module/dict/book")
public class DictBookController extends BaseController
{
    @Autowired
    private IDictBookService dictBookService;

    @Autowired
    private IDictBookUserService dictBookUserService;

    @Autowired
    private DictWordMapper dictWordMapper;

    private final ObjectMapper objectMapper = new ObjectMapper();

    /**
     * 查询词典列表（后台管理专用，只查询系统内置词典）
     */
    @PreAuthorize("@ss.hasPermi('module:dict:book:list')")
    @GetMapping("/list")
    public TableDataInfo list(DictBook dictBook)
    {
        startPage();
        Long userId = getUserId();
        
        // 默认只查询系统内置词典（source_type='0'），不包括用户自定义词典
        if (dictBook.getSourceType() == null || dictBook.getSourceType().isEmpty()) {
            dictBook.setSourceType("0");
        }
        
        // admin用户可以看到所有系统词典
        if (userId != null && userId == 1L) {
            List<DictBook> list = dictBookService.selectDictBookList(dictBook);
            return getDataTable(list);
        }
        
        // 普通用户只能看到有权限的系统词典
        List<DictBook> list = dictBookService.selectDictBookListByUserId(dictBook, userId);
        return getDataTable(list);
    }

    /**
     * 查询词典列表（带标签，支持标签筛选）
     */
    @PreAuthorize("@ss.hasPermi('module:dict:book:list')")
    @GetMapping("/listWithTags")
    public TableDataInfo listWithTags(DictBook dictBook)
    {
        startPage();
        List<DictBook> list = dictBookService.selectDictBookListWithTags(dictBook);
        return getDataTable(list);
    }

    /**
     * 根据语言分类查询词典列表
     */
    @GetMapping("/list/{languageCategory}")
    public AjaxResult listByLanguageCategory(@PathVariable("languageCategory") String languageCategory)
    {
        List<DictBook> list = dictBookService.selectDictBookListByLanguageCategory(languageCategory);
        return success(list);
    }

    /**
     * 根据ID查询词典详情
     */
    @PreAuthorize("@ss.hasPermi('module:dict:book:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") String id)
    {
        return success(dictBookService.selectDictBookById(id));
    }

    /**
     * 新增词典
     */
    @PreAuthorize("@ss.hasPermi('module:dict:book:add')")
    @Log(title = "词典管理", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody DictBook dictBook)
    {
        dictBook.setCreateBy(getUsername());
        return toAjax(dictBookService.insertDictBook(dictBook));
    }

    /**
     * 修改词典
     */
    @PreAuthorize("@ss.hasPermi('module:dict:book:edit')")
    @Log(title = "词典管理", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody DictBook dictBook)
    {
        dictBook.setUpdateBy(getUsername());
        return toAjax(dictBookService.updateDictBook(dictBook));
    }

    /**
     * 删除词典
     */
    @PreAuthorize("@ss.hasPermi('module:dict:book:remove')")
    @Log(title = "词典管理", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable String[] ids)
    {
        return toAjax(dictBookService.deleteDictBookByIds(ids));
    }

    // ==================== 词典用户权限管理接口 ====================

    /**
     * 查询词典的授权用户列表
     */
    @PreAuthorize("@ss.hasPermi('module:dict:book:user')")
    @GetMapping("/user/{bookId}")
    public AjaxResult getBookUsers(@PathVariable("bookId") String bookId)
    {
        List<DictBookUser> list = dictBookUserService.selectDictBookUserListByBookId(bookId);
        return success(list);
    }

    /**
     * 为词典添加授权用户
     */
    @PreAuthorize("@ss.hasPermi('module:dict:book:user')")
    @Log(title = "词典用户管理", businessType = BusinessType.INSERT)
    @PostMapping("/user/{bookId}")
    public AjaxResult addBookUsers(@PathVariable("bookId") String bookId, @RequestBody Long[] userIds)
    {
        return toAjax(dictBookUserService.batchInsertDictBookUser(bookId, userIds, getUsername()));
    }

    /**
     * 删除词典的授权用户
     */
    @PreAuthorize("@ss.hasPermi('module:dict:book:user')")
    @Log(title = "词典用户管理", businessType = BusinessType.DELETE)
    @DeleteMapping("/user/{bookId}")
    public AjaxResult removeBookUsers(@PathVariable("bookId") String bookId, @RequestBody Long[] userIds)
    {
        return toAjax(dictBookUserService.deleteDictBookUserByBookIdAndUserIds(bookId, userIds));
    }

    /**
     * 查询当前用户有权限的词典列表
     */
    @GetMapping("/my")
    public AjaxResult getMyBooks()
    {
        Long userId = getUserId();
        List<DictBookUser> list = dictBookUserService.selectDictBookUserListByUserId(userId);
        return success(list);
    }

    /**
     * 查询用户可访问的词典列表（公开接口，无需权限）
     * 只查询系统内置词典（source_type='0'），不包括用户自定义词典
     * 返回规则：
     * - 未登录用户：只返回免费词典 (isFree='1')
     * - 已登录用户：返回免费词典 (isFree='1') + 已授权词典
     */
    @GetMapping("/user/list")
    public TableDataInfo getUserDictList(DictBook dictBook)
    {
        startPage();
        Long userId = getUserId();
        
        if (userId != null) {
            // 已登录用户：返回免费词典 + 已授权的系统内置词典
            logger.info("用户 {} 查询可访问的系统词典列表", userId);
            List<DictBook> list = dictBookService.selectDictBookListByUserId(dictBook, userId);
            return getDataTable(list);
        } else {
            // 未登录用户：只返回免费的系统内置词典
            logger.info("未登录用户查询免费系统词典列表");
            dictBook.setIsFree("1");
            dictBook.setSourceType("0"); // 只查询系统词典
            List<DictBook> list = dictBookService.selectDictBookList(dictBook);
            return getDataTable(list);
        }
    }

    /**
     * 检查当前用户是否有词典访问权限
     */
    @GetMapping("/check/{bookId}")
    public AjaxResult checkPermission(@PathVariable("bookId") String bookId)
    {
        Long userId = getUserId();
        boolean hasPermission = dictBookUserService.checkUserBookPermission(bookId, userId);
        return success(hasPermission);
    }

    /**
     * 导入词典文件（支持JSON和Word文档）
     */
    @PreAuthorize("@ss.hasPermi('module:dict:book:add')")
    @Log(title = "词典导入", businessType = BusinessType.IMPORT)
    @PostMapping("/import")
    public AjaxResult importDictFile(
            @RequestParam("file") MultipartFile file,
            @RequestParam("dictBook") String dictBookJson)
    {
        try {
            // 解析词典信息
            DictBook dictBook = objectMapper.readValue(dictBookJson, DictBook.class);
            dictBook.setCreateBy(getUsername());
            
            String fileName = file.getOriginalFilename();
            if (fileName == null || fileName.isEmpty()) {
                return error("文件名不能为空");
            }
            
            int dotIndex = fileName.lastIndexOf('.');
            if (dotIndex == -1) {
                return error("无效的文件格式");
            }
            String fileType = fileName.substring(dotIndex).toLowerCase();
            
            // 解析单词数据
            List<DictWord> words;
            if (".json".equals(fileType)) {
                words = parseJsonFile(file, dictBook);
            } else if (".doc".equals(fileType) || ".docx".equals(fileType)) {
                words = parseWordFile(file, dictBook);
            } else {
                return error("不支持的文件格式：" + fileType);
            }
            
            if (words == null || words.isEmpty()) {
                return error("文件中没有找到有效的单词数据");
            }
            
            // 更新词典的单词数量
            dictBook.setLength(words.size());
            
            // 保存词典信息
            int dictResult = dictBookService.insertDictBook(dictBook);
            if (dictResult <= 0) {
                return error("保存词典信息失败");
            }
            
            // 批量插入单词
            int wordCount = batchInsertWords(words);
            
            return success(String.format("词典导入成功！共导入 %d 个单词", wordCount));
            
        } catch (Exception e) {
            logger.error("导入词典失败", e);
            return error("导入词典失败：" + e.getMessage());
        }
    }

    /**
     * 解析JSON文件
     */
    private List<DictWord> parseJsonFile(MultipartFile file, DictBook dictBook) throws Exception {
        List<DictWord> words = new ArrayList<>();
        
        // 读取JSON内容
        String jsonContent = new String(file.getBytes(), StandardCharsets.UTF_8);
        List<Map<String, Object>> jsonArray = objectMapper.readValue(
            jsonContent, 
            new TypeReference<List<Map<String, Object>>>() {}
        );
        
        // 转换为DictWord对象
        for (Map<String, Object> item : jsonArray) {
            DictWord word = new DictWord();
            word.setBookId(dictBook.getId());
            
            // 处理单词字段（支持多种格式）
            String wordText = getStringValue(item, "name", "word");
            if (StringUtils.isEmpty(wordText)) {
                continue; // 跳过没有单词的条目
            }
            word.setWord(wordText);
            
            // 处理翻译（支持数组或字符串）
            Object transObj = item.get("trans");
            if (transObj instanceof List) {
                @SuppressWarnings("unchecked")
                List<String> transList = (List<String>) transObj;
                word.setTranslation(String.join("; ", transList));
            } else if (transObj != null) {
                word.setTranslation(transObj.toString());
            }
            
            // 处理音标
            word.setPhoneticUs(getStringValue(item, "usphone", "phonetic_us"));
            word.setPhoneticUk(getStringValue(item, "ukphone", "phonetic_uk"));
            
            // 处理日语假名标注
            word.setNotation(getStringValue(item, "notation"));
            
            // 处理例句
            word.setExampleSentence(getStringValue(item, "example", "exampleSentence"));
            
            words.add(word);
        }
        
        return words;
    }

    /**
     * 解析Word文件
     */
    private List<DictWord> parseWordFile(MultipartFile file, DictBook dictBook) throws Exception {
        List<DictWord> words = new ArrayList<>();
        
        // 使用BufferedReader逐行读取
        try (BufferedReader reader = new BufferedReader(
                new InputStreamReader(file.getInputStream(), StandardCharsets.UTF_8))) {
            
            String line;
            int lineNumber = 0;
            
            while ((line = reader.readLine()) != null) {
                lineNumber++;
                line = line.trim();
                
                // 跳过空行和注释行
                if (line.isEmpty() || line.startsWith("#") || line.startsWith("//")) {
                    continue;
                }
                
                // 解析格式：单词 | 翻译 或 单词\t翻译
                String[] parts = null;
                if (line.contains("|")) {
                    parts = line.split("\\|", 2);
                } else if (line.contains("\t")) {
                    parts = line.split("\t", 2);
                } else {
                    // 尝试用空格分割（至少2个空格）
                    parts = line.split("\\s{2,}", 2);
                }
                
                if (parts != null && parts.length >= 2) {
                    DictWord word = new DictWord();
                    word.setBookId(dictBook.getId());
                    word.setWord(parts[0].trim());
                    word.setTranslation(parts[1].trim());
                    words.add(word);
                } else {
                    logger.warn("第 {} 行格式不正确，已跳过：{}", lineNumber, line);
                }
            }
        }
        
        return words;
    }

    /**
     * 批量插入单词
     */
    private int batchInsertWords(List<DictWord> words) {
        int count = 0;
        int batchSize = 1000;
        
        for (int i = 0; i < words.size(); i += batchSize) {
            int end = Math.min(i + batchSize, words.size());
            List<DictWord> batch = words.subList(i, end);
            
            for (DictWord word : batch) {
                try {
                    dictWordMapper.insertDictWord(word);
                    count++;
                } catch (Exception e) {
                    logger.warn("插入单词失败: {}", word.getWord(), e);
                }
            }
        }
        
        return count;
    }

    /**
     * 从Map中获取字符串值（支持多个可能的key）
     */
    private String getStringValue(Map<String, Object> map, String... keys) {
        for (String key : keys) {
            Object value = map.get(key);
            if (value != null && !value.toString().trim().isEmpty()) {
                return value.toString().trim();
            }
        }
        return null;
    }
}

